<template>
  <view class="index">
    <!-- 用户信息 -->
    <view class="head">
      <view class="head_box flex-row" style="justify-content:left">
        <view class="user_ava">
          <open-data type="userAvatarUrl"></open-data>
        </view>
        <view>
          <view class="user_name" v-if="username !== undefined">{{ username }} <text>{{ tip }}</text></view>
          <view class="user_add">新的一天开始了，加油哦~</view>
        </view>
        <view class="mealBtn" @tap="ToPrayTap">
          <image src="/static/page_icons/meal.png"></image>
          <view class="mealText">{{ is_pray == 2 ? '已祈福' : '未祈福' }}</view>
        </view>
      </view>
    </view>

    <view class="contentBox">
      <!-- 打卡记录 -->
      <view class="signRecord">
        <view class="signInfo">上班打卡
          <text class="text-green">{{ clockRecords[0] ? clockRecords[0].times : onWorkTime? onWorkTime:'未打卡' }}</text>
          <view class="sign_address">
            <view class="">{{ clockRecords[0] ? clockRecords[0].address : '暂无打卡地址' }}</view>
          </view>
        </view>
        <view class="signInfo">下班打卡
          <text class="text-green">{{ clockRecords[1] ? clockRecords[1].times : offDutyTime?offDutyTime:'未打卡' }}</text>
          <view class="sign_address">
            <view class="">{{ clockRecords[1] ? clockRecords[1].address : '暂无打卡地址' }}</view>
          </view>
        </view>
      </view>
      <view class="dateInfo">
        <text>{{ nowDate }} {{ nowDay }}</text>
      </view>
      <view class="c_clock flex-column">
        <view class="clock_time flex-column j_c " :class="{ c1: status === 1 }" v-if="signType === 0"
          @tap="signTap_onWork">
          <text>上班打卡</text>
          <text>{{ now_time }}</text>
        </view>
        <view class="clock_time flex-column j_c " :class="{ c1: status === 1, outArea: is_out === 2 }" v-else
          @tap="signTap_offDuty">
          <text>下班打卡</text>
          <text>{{ now_time }}</text>
        </view>
        <view class="clock_time_over flex-column j_c" :class="{ c2: status === 1 }" @tap="sign_tap_already">
          <text>{{ signType === 0 ? '已上班打卡' : '已下班打卡' }}</text>
          <text>{{ now_time }}</text>
        </view>
      </view>
      <!-- 打卡地址 -->
      <view class="clock_address ">
        <image src="/static/page_icons/add0.png" class="add_icon" />
        <text>{{ current_address }}</text>
      </view>
      <view class="refresh" @tap="refreshAdd">刷新位置</view>
    </view>
  </view>
</template>

<script>
  import bageMix from '@/mixins/auth.js'
  import tabbar from '@/mixins/tabbar-badge.js'
  import util from '@/utils/fromat_clock.js'
  import {
    getTime
  } from '@/utils/format.js'
  import qqMapSdk from '@/lib/qqmap-wx-jssdk.js'
  import {
    mapActions,
    mapState,
    mapMutations
  } from 'vuex'
  export default {
    mixins: [bageMix, tabbar],
    computed: {
      ...mapState('m_clock', [
        'status_clock',
        'clockRecords',
        'status',
        'signType',
        'is_out',
        'now_time_stop',
        'onWorkTime',
        'offDutyTime'
      ]),
      deptId() {
        return this.$store.state.m_user.employeeInfo?.department
      },
      username() {
        return this.$store.state.m_user.employeeInfo?.username
      },
      deptType() {
        return this.$store.state.m_user.employeeInfo?.deptType
      }
    },
    data() {
      return {
        queryObj: {
          checkInDate: '',
          onWorkTime: null,
          offDutyTime: null,
          longitude: '',
          latitude: ''
        },
        checkTimeObj: {
          setDeptId: 1,
          setStartDate: null,
          setEndDate: null,
          setStartTime: null,
          setEndTime: null
        },
        is_pray: 1, //1祈福 2已祈福
        now_time: '', //当前时间 00:45:49
        nowDate: '', //当前年月日
        nowDay: '', //星期几  星期五
        tip: '', //提示 上午好、下午好
        current_address: '', //当前定位地址
        time: null
      };
    },
    onLoad() {
      this.nowDate = util.formatTime(new Date())
      this.nowDay = util.formatDay(new Date())
      this.tip = util.formatSole()
      this.now_time = getTime() // 获取当前时间
      this.getCurrentTime() // 初始化一次时间然后启动定时器
      this.queryObj.checkInDate = util.getTime(new Date())
      this.loadClockState()
    },
    watch: {
      // 监听 token 变化，确保登录后执行初始化逻辑
      '$store.state.m_user.token': {
        immediate: true, // 添加此选项，初始化时立即触发
        handler(newVal) {
          if (newVal && newVal !== '') {
            // 获取初始位置信息
            this.getUserAuth(); // getUserAuth 会调用 getLocation
          }
        },
      }
    },
    onShow() {
      if (this.$store.state.m_user.token && this.$store.state.m_user.token !== '') {
        this.checkNewDay().then(isNewDay => {
          if (!isNewDay) {
            this.getRecordsData(); // 保持获取最新记录
          }
          this.getgetCheckInTime()
        })
      }
      if (!this.time) {
        this.getCurrentTime()
      }
    },
    onHide() {
      // 页面隐藏时启动时间更新
      this.stopTimeUpdate()
      if (this.$store.state.m_user.token && this.$store.state.m_user.token !== '') {
        this.saveClockState()
      }
    },
    onunload() {
      // 页面卸载时停止更新时间并保存状态
      this.stopTimeUpdate()
      if (this.$store.state.m_user.token && this.$store.state.m_user.token !== '') {
        this.saveClockState()
      }
    },

    methods: {
      ...mapActions('m_clock', ['getRecordsData', 'saveClockState', 'loadClockState', 'checkNewDay']),
      ...mapMutations('m_clock', ['UPDATE_CLOCK_STATE', 'RESET_STATE']),
      // 检查当前打卡类型和状态
      checkClockStatus() {
        const currentTime = this.now_time
        const {
          setEndTime
        } = this.checkTimeObj

        // 如果已经上班打卡且到达下班时间，切换到下班打卡,这里的话就不用去修改了
        if (this.clockRecords[0] && !this.clockRecords[1] && util.timeToSeconds(currentTime) >= util.timeToSeconds(
            setEndTime)) {
          this.UPDATE_CLOCK_STATE({
            signType: 1
          })
          this.saveClockState()
          // 只有在未打卡状态下才重置 status
          if (this.status === 1) {
            this.UPDATE_CLOCK_STATE({
              status: 0,
              now_time_stop: ''
            })
            this.saveClockState()
          }
        }
      },
      async signTap_onWork() {
        try {
          const time = this.now_time
          const {
            setStartTime,
            setEndTime
          } = this.checkTimeObj

          // 判断是否在合理的打卡时间范围内
          if (this.isInReasonableRange(time, setStartTime, setEndTime)) {
            this.queryObj.onWorkTime = time
            await uni.$http.post('/attendance/location', this.queryObj)
            const newClockRecords = [{
              times: this.now_time,
              address: this.current_address,
              isLate: this.isLate(time, setStartTime)
            }]

            this.UPDATE_CLOCK_STATE({
              clockRecords: newClockRecords,
              status: 1,
              signType: 0,
              is_out: 2,
              status_clock: 0,
              now_time_stop: this.now_time,
            })
            this.saveClockState()
            this.checkClockStatus()
            uni.vibrateLong()

            // 如果迟到，显示提示
            if (this.clockRecords[0].isLate) {
              uni.$showMsg('已完成补卡，请注意按时打卡', 2000)
            }
          } else {
            uni.$showMsg('不在打卡时间范围内，请在工作时间内打卡', 2000)
          }
        } catch (error) {
          uni.$showMsg('签到失败，请检查网络')
          if (this.deptId) {
            this.getgetCheckInTime(); // 获取部门的打卡信息
          }
        }
      },
      // 判断是否在合理的打卡时间范围内
      isInReasonableRange(currentTime, startTime, endTime) {
        const currentSeconds = util.timeToSeconds(currentTime)
        const startSeconds = util.timeToSeconds(startTime)
        const endSeconds = util.timeToSeconds(endTime)

        // 允许在上班时间前30分钟开始打卡，直到下班时间
        const earlyStartSeconds = startSeconds - 30 * 60 // 提前30分钟
        return currentSeconds >= earlyStartSeconds && currentSeconds <= endSeconds
      },
      // 判断是否迟到
      isLate(currentTime, startTime) {
        const currentSeconds = util.timeToSeconds(currentTime)
        const startSeconds = util.timeToSeconds(startTime)
        // 超过上班时间10分钟算迟到
        const lateSeconds = startSeconds + 10 * 60
        return currentSeconds > lateSeconds
      },
      async signTap_offDuty() {
        try {
          const time = this.now_time
          const {
            setEndTime
          } = this.checkTimeObj
          // 检查是否已经上班打卡
          if (!this.clockRecords[0]) {
            uni.$showMsg('请先完成上班打卡', 2000)
            return
          }
          // 判断是否可以下班打卡
          if (this.isInOffDutyRange(time, setEndTime)) {
            this.queryObj.offDutyTime = time
            await uni.$http.post('/attendance/location', this.queryObj)
            uni.vibrateLong()
            // 更新打卡记录
            const newClockRecords = [
              this.clockRecords[0],
              {
                times: this.now_time,
                address: this.current_address,
                isOvertime: this.isOvertime(time, setEndTime)
              },
            ]
            this.UPDATE_CLOCK_STATE({
              clockRecords: newClockRecords,
              status: 1,
              now_time_stop: this.now_time,
              status_clock: 1,
              signType: 1,
            })
            // 根据是否加班 显示不同提示
            if (this.clockRecords[1].isOvertime) {
              uni.$showMsg('加班打卡成功，辛苦了!!', 2000)
            } else {
              uni.$showMsg('下班打卡成功!', 2000)
            }
          } else {
            // 如果在下班时间之前尝试打卡
            if (this.isEarlyLeave(time, setEndTime)) {
              const that = this
              uni.showModal({
                title: '提示',
                content: '还未到下班时间,你确认要提前打卡吗？',
                confirmText: '确认',
                cancelText: '取消',
                async success(res) {
                  if (res && res.confirm) {
                    that.queryObj.offDutyTime = time
                    await uni.$http.post('/attendance/location', that.queryObj)
                    const newClockRecords = [
                      that.clockRecords[0],
                      {
                        times: that.now_time,
                        address: that.current_address,
                        isOvertime: that.isOvertime(time, setEndTime)
                      },
                    ]
                    that.UPDATE_CLOCK_STATE({
                      clockRecords: newClockRecords,
                      status: 1, // 触发翻转动画
                      signType: 1, // 上班打卡
                      status_clock: 1,
                      now_time_stop: that.now_time, // 记录打卡时间                     
                    })
                    that.saveClockState()
                    uni.vibrateLong()
                    uni.$showMsg('之后请不要频繁去早退哟,祝你生活愉快!!!')
                  }
                }
              })
              return
            }
            uni.$showMsg('打卡失败，请检查网络')
          }
        } catch (error) {
          uni.$showMsg('签到失败，请检查网络', 2000)
        }
      },
      // 判断是否可以下班打卡
      isInOffDutyRange(currentTime, endTime) {
        const currentSeconds = util.timeToSeconds(currentTime)
        const endSeconds = util.timeToSeconds(endTime)
        // 只允许在下班时间及之后打卡
        return currentSeconds >= endSeconds
      },
      // 判断是否早退
      isEarlyLeave(currentTime, endTime) {
        const currentSeconds = util.timeToSeconds(currentTime)
        const endSeconds = util.timeToSeconds(endTime)
        return currentSeconds < endSeconds
      },
      // 判断是否加班 
      isOvertime(currentTime, endTime) {
        const currentSeconds = util.timeToSeconds(currentTime)
        const endSeconds = util.timeToSeconds(endTime)
        // 超过下班时间30分钟算加班
        const overtimeSeconds = endSeconds + 30 * 60
        return currentSeconds >= overtimeSeconds
      },

      //已完成上班打卡时，已打卡是否可以去进行下班打卡
      sign_tap_already() {
        if (this.status_clock === 0) {
          this.signTap_offDuty()
          return
        }
        uni.$showMsg('你已经完成了上下班的打卡任务，你不需要再去进行打卡了!!!')
      },
      /**
       * @description  获取部门设置打卡时间
       */
      async getgetCheckInTime() {
        console.log('获取部门打卡时间了')
        if (this.deptId === null) return uni.$showMsg('没有部门id，请点击页面按钮重新获取')
        const {
          data: res
        } = await uni.$http.get(`/attendance/getCheckInTime?deptId=${this.deptId}&deptType=${this.deptType}`)
        this.checkTimeObj = {
          setDeptId: res.data.setDeptId,
          setStartDate: res.data.setStartDate,
          setEndDate: res.data.setEndDate,
          setStartTime: res.data.setStartTime,
          setEndTime: res.data.setEndTime
        }
      },
      // 修改getCurrentTime 方法
      getCurrentTime: function() {
        // 如果定时器已存在，则不再创建新的
        if (this.time) {
          return;
        }
        this.time = setInterval(() => {
          this.now_time = getTime()
        }, 1000)
      },
      // 停止更新时间
      stopTimeUpdate() {
        if (this.time) {
          clearInterval(this.time)
          this.time = null
        }
      },
      ToPrayTap: function(e) {
        uni.$showMsg('祈福成功，祝你有更加愉快的一天')
        this.is_pray = 2
      },
      getLocation() {
        const that = this
        const QQMapWX = new qqMapSdk({
          key: 'VJ5BZ-A4I6C-3L42Z-ALWBM-Z2TOO-DKBQM'
        })
        console.log(QQMapWX)
        uni.getLocation({
          type: 'gcj02',
          success: (res) => {
            that.queryObj.latitude = res.latitude
            that.queryObj.longitude = res.longitude
            QQMapWX.reverseGeocoder({
              location: {
                latitude: res.latitude,
                longitude: res.longitude,
              },
              success: function(res) {
                const address = res.result.address + res.result.formatted_addresses.recommend;
                that.current_address = address
              },
              fail: (err) => {
                console.log('逆地址解析失败:', err);
              }
            })
          },
          fail: (error) => {
            console.log(error)
            uni.showModal({
              title: '提示',
              content: error || '获取定位失败，请打开手机定位，重新获取!!!',
              showCancel: false,
              confirmText: '确认'
            })
          }
        })
      },
      // 请求获取定位权限
      getUserAuth() {
        let that = this
        // 获取用户是否开启 授权获取当前的地理位置、速度的权限
        uni.getSetting({
          success(res) {
            if (!res.authSetting['scope.userLocation']) {
              uni.authorize({
                scope: 'scope.userLocation',
                success() {
                  that.getLocation()
                },
                fail() {
                  uni.showModal({
                    title: '提示',
                    content: '若点击不授权，将无法使用位置功能',
                    cancelText: '不授权',
                    cancelColor: '#999',
                    confirmText: '授权',
                    confirmColor: '#f94218',
                    success(res) {
                      console.log(res)
                      if (res.confirm) {
                        // 选择弹框内授权
                        uni.openSetting({
                          success(res) {
                            console.log(res.authSetting)
                          }
                        })
                      } else if (res.cancel) {
                        // 选择弹框内 不授权
                        console.log('用户点击不授权')
                      }
                    }
                  })
                }
              })
            } else {
              // 有权限直接放过
              that.getLocation()
            }

          },
        })
      },
      refreshAdd() {
        this.getUserAuth()
      }
    }
  }
</script>

<style lang="scss">
  page {
    background-color: #f1f1f1;
    height: calc(100% - 10px);

    view,
    scroll-view,
    swiper,
    button,
    input,
    textarea,
    label,
    navigator,
    image {
      box-sizing: border-box;
    }
  }

  .index {
    margin-top: 10px;
    background-color: #fff;
    min-height: 100%;

    .head {
      padding-bottom: 10rpx;
      border-bottom: 2rpx solid #e5e5e5;

      .head_box {
        padding: 26rpx 28rpx 8px;
        width: 750rpx;

        &.flex-row {
          width: 100%;
          display: flex;
          flex-direction: row;
          align-items: center;
          justify-content: center;
        }

        .user_ava {
          width: 116rpx;
          height: 116rpx;
          overflow: hidden;
          border-radius: 25%;
          margin-right: 32rpx;
        }

        .user_name {
          font-size: 32rpx;
          font-weight: 600;
          color: #333333;
          margin-bottom: 18rpx;

          text {
            font-size: 24rpx;
            color: #999999;
            font-weight: 400;
            margin-left: 20rpx;
          }
        }

        .user_add {
          font-size: 28rpx;
          color: #3380f3;
        }

        .mealBtn {
          position: absolute;
          right: 15px;

          image {
            margin-left: 4rpx;
            width: 27px;
            height: 27px;
          }

          .mealText {
            font-size: 12px;
            color: #999999;
          }
        }
      }
    }

    .contentBox {
      padding: 44rpx 28rpx;

      .signRecord {
        display: flex;
        flex-flow: row nowrap;
        justify-content: space-between;
        margin-top: 10px;

        .signInfo {
          width: 48%;
          height: 65px;
          background: #f1f1f1;
          padding: 10px;
          padding-bottom: 1px;
          border-radius: 5px;
          box-sizing: border-box;

          .text-green {
            color: green;
          }

          text {
            float: inline-end;
          }

          .sign_address {
            display: flex;
            margin-top: 5px;

            view {
              white-space: nowrap;
              text-overflow: ellipsis;
              overflow: hidden;
              font-size: 14px;
              margin-top: 1px !important;
              color: #5f5a5a;
            }
          }
        }
      }
    }

    .dateInfo {
      text-align: center;
      position: relative;
      top: 50px;
      font-size: 35rpx;
    }

    .c_clock {
      margin: 180rpx auto 0;
      width: 350rpx;
      height: 380rpx;
      perspective: 1500;
      -webkit-perspective: 1500;
      -moz-perspective: 1500;

      &.flex-column {
        width: 100%;
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
      }

      .clock_time {
        width: 350rpx;
        height: 350rpx;
        margin-bottom: 30rpx;
        position: absolute;
        transition: all 1s;
        backface-visibility: hidden;

        &.c1 {
          transform: rotateY(180deg);

          &::after {
            animation: none !important;
          }
        }

        &.outArea::before {
          background: #f44336 !important;
        }

        text {
          position: relative;
          z-index: 13;
          color: #FFFFFF;

          &:first-child {
            font-size: 36rpx;
            margin-bottom: 14rpx;
          }

          &:last-child {
            font-size: 45rpx;
          }
        }

        &::after {
          content: '';
          top: 0;
          left: 25%;
          width: 350rpx;
          height: 350rpx;
          border-radius: 50%;
          position: absolute;
          z-index: 9;
          background: rgba(48, 124, 237, 0.08);
          animation: scale 1s infinite alternate-reverse;
        }

        &::before {
          position: absolute;
          z-index: 11;
          content: '';
          width: 320rpx;
          height: 320rpx;
          background: rgba(48, 124, 237, 0.79);
          border-radius: 50%;
          top: 50%;
          left: 50%;
          transform: translate(-50%, -50%);
        }

        &.flex-column {
          width: 100%;
          display: flex;
          flex-direction: column;
          align-items: center;
          justify-content: center;
        }
      }

      .clock_time_over {
        display: flex;
        flex-direction: column;
        width: 350rpx;
        height: 350rpx;
        margin-bottom: 30rpx;
        border-radius: 50%;
        background: rgba(48, 124, 237, 0.08);
        position: absolute;
        transition: all 1s;
        backface-visibility: hidden;
        transform: rotateY(-180deg);

        &::after {
          position: absolute;
          z-index: 11;
          content: '';
          width: 320rpx;
          height: 320rpx;
          background: #C6CED9;
          border-radius: 50%;
          top: 50%;
          left: 50%;
          transform: translate(-50%, -50%);
        }

        &.c2 {
          transform: rotateY(0deg);
        }

        text {
          left: 25%;
          top: 40%;
          position: relative;
          z-index: 12;
          color: #FFFFFF;

          &:first-child {
            font-size: 36rpx;
            margin-bottom: 14rpx;
          }

          &:last-child {
            font-size: 45rpx;
          }
        }
      }
    }

    .clock_address {
      text-align: center;
      font-size: 30rpx;
      color: #333333;
      width: 80%;
      margin: 20px auto;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;

      text {
        vertical-align: middle;
      }

      .add_icon {
        width: 28rpx;
        height: 36rpx;
        margin-right: 16rpx;
        vertical-align: middle;
      }
    }

    .refresh {
      margin-top: 25px;
      color: #307CED;
      display: flex;
      align-items: center;
      justify-content: center;
    }

    @keyframes scale {
      0% {
        transform: scale(1.1);
      }

      100% {
        transform: scale(1);
      }
    }
  }
</style>